package com.cz.run.config.mybatis;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @author CAIYJ
 * @Description: TODO()
 * @Date:2018/5/14 9:31
 */
@Configuration
@MapperScan(basePackages = "com.cz.run.mapper", sqlSessionTemplateRef = "runSqlSessionTemplate")
public class DataSourceConfig {
    private static final Logger logger = LogManager
            .getLogger(DataSourceConfig.class);

    @Bean(name = "runDataSource", initMethod = "init", destroyMethod = "close")
    @Primary
    public DruidDataSource dataSource(
            DataSourceProperties dataSourceProperties)
            throws SQLException {
        logger.info("初始化runDataSource");
        try (DruidDataSource druidDataSource = new DruidDataSource()) {
            druidDataSource.setDriverClassName(
                    dataSourceProperties.getDriverClassName());
            druidDataSource.setUrl(dataSourceProperties.getUrl());
            druidDataSource.setUsername(dataSourceProperties.getUsername());
            druidDataSource.setPassword(dataSourceProperties.getPassword());
            druidDataSource
                    .setInitialSize(dataSourceProperties.getMinIdle());
            druidDataSource.setMinIdle(dataSourceProperties.getMinIdle());
            druidDataSource
                    .setMaxActive(dataSourceProperties.getMaxActive());
            druidDataSource.setMaxWait(dataSourceProperties.getMaxWait());
            druidDataSource
                    .setTimeBetweenEvictionRunsMillis(dataSourceProperties
                            .getTimeBetweenEvictionRunsMillis());
            druidDataSource.setMinEvictableIdleTimeMillis(
                    dataSourceProperties.getMinEvictableIdleTimeMillis());
            druidDataSource.setValidationQuery(
                    dataSourceProperties.getValidationQuery());
            druidDataSource.setTestWhileIdle(
                    dataSourceProperties.getTestWhileIdle());
            druidDataSource.setTestOnBorrow(
                    dataSourceProperties.getTestOnBorrow());
            druidDataSource.setTestOnReturn(
                    dataSourceProperties.getTestOnReturn());
            druidDataSource.setPoolPreparedStatements(
                    dataSourceProperties.getPoolPreparedStatements());
            druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(
                    dataSourceProperties
                            .getMaxPoolPreparedStatementPerConnectionSize());
            druidDataSource.setFilters(dataSourceProperties.getFilters());
            return druidDataSource;
        }
    }

    @Bean(name = "runSqlSessionFactory")
    @Primary
    public SqlSessionFactory sqlSessionFactory(
            @Qualifier("runDataSource") DataSource dataSource,
            @Qualifier("basisGlobalConfig") GlobalConfiguration globalConfiguration) throws Exception {
//        String mapperLocations = "classpath:mapper/run/*.xml";
        String configLocation = "classpath:mybatis-sqlconfig.xml";
        String typeAliasesPackage = "com.cz.run.beans.mysql";
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        // 数据源
        factory.setDataSource(dataSource);
        // 全局配置
        factory.setGlobalConfig(globalConfiguration);
        Interceptor[] interceptor = {new PaginationInterceptor()};
        // 分页插件
        factory.setPlugins(interceptor);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            // 自动扫描Mapping.xml文件
//            factory.setMapperLocations(resolver.getResources(mapperLocations));
            factory.setConfigLocation(resolver.getResource(configLocation));
            factory.setTypeAliasesPackage(typeAliasesPackage);
            return factory.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    // MyBatis 动态扫描
    @Bean(name = "runMapperScannerConfigurer")
    public MapperScannerConfigurer mapperScannerConfigurer() {
        logger.info("初始化runMapperScannerConfigurer");
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        String basePackage = "com.cz.run.mapper";
        mapperScannerConfigurer.setBasePackage(basePackage);
        return mapperScannerConfigurer;
    }

    @Bean(name = "runTransactionManager")
    @Primary
    public DataSourceTransactionManager transactionManager(
            @Qualifier("runDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "runSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("runSqlSessionFactory") SqlSessionFactory sqlSessionFactory)
            throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
